home *** CD-ROM | disk | FTP | other *** search
- Subject: v08i023: The JOVE text editor, Part04/13
- Newsgroups: mod.sources
- Approved: mirror!rs
-
- Submitted by: seismo!rochester!jpayne (Jonathan Payne)
- Mod.sources: Volume 8, Issue 23
- Archive-name: jove/Part04
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- # If all goes well, you will see the message "End of archive 4 (of 13)."
- # Contents: io.c iproc-pipes.c iproc-ptys.c iproc.c keymaps.txt rec.c
- PATH=/bin:/usr/bin:/usr/ucb; export PATH
- echo shar: extracting "'io.c'" '(20767 characters)'
- if test -f 'io.c' ; then
- echo shar: will not over-write existing file "'io.c'"
- else
- sed 's/^X//' >io.c <<'@//E*O*F io.c//'
- X/************************************************************************
- X * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is *
- X * provided to you without charge, and with no warranty. You may give *
- X * away copies of JOVE, including sources, provided that this notice is *
- X * included in all the files. *
- X ************************************************************************/
- X
- X#include "jove.h"
- X#include "io.h"
- X#include "termcap.h"
- X
- X#ifdef IPROCS
- X# include <signal.h>
- X#endif
- X
- X#include <sys/stat.h>
- X#include <sys/file.h>
- X#include <errno.h>
- X
- X#ifndef W_OK
- X# define W_OK 2
- X# define F_OK 0
- X#endif
- X
- Xlong io_chars; /* number of chars in this open_file */
- Xint io_lines; /* number of lines in this open_file */
- Xprivate int tellall; /* display file io info? */
- X
- X#ifdef VMUNIX
- Xchar iobuff[LBSIZE],
- X genbuf[LBSIZE],
- X linebuf[LBSIZE];
- X#else
- Xchar *iobuff,
- X *genbuf,
- X *linebuf;
- X#endif
- X
- X#ifdef BACKUPFILES
- Xint BkupOnWrite = 0;
- X#endif
- X
- Xclose_file(fp)
- XFile *fp;
- X{
- X if (fp) {
- X f_close(fp);
- X if (tellall != QUIET)
- X add_mess(" %d lines, %D characters.",
- X io_lines,
- X io_chars);
- X }
- X}
- X
- X/* Write the region from line1/char1 to line2/char2 to FP. This
- X never CLOSES the file since we don't know if we want to. */
- X
- Xint EndWNewline = 1;
- X
- Xputreg(fp, line1, char1, line2, char2, makesure)
- Xregister File *fp;
- XLine *line1,
- X *line2;
- X{
- X register int c;
- X register char *lp;
- X
- X if (makesure)
- X (void) fixorder(&line1, &char1, &line2, &char2);
- X while (line1 != line2->l_next) {
- X lp = lcontents(line1) + char1;
- X if (line1 == line2) {
- X fputnchar(lp, (char2 - char1), fp);
- X io_chars += (char2 - char1);
- X } else while (c = *lp++) {
- X putc(c, fp);
- X io_chars++;
- X }
- X if (line1 != line2) {
- X io_lines++;
- X io_chars++;
- X putc('\n', fp);
- X }
- X line1 = line1->l_next;
- X char1 = 0;
- X }
- X flush(fp);
- X}
- X
- Xread_file(file, is_insert)
- Xchar *file;
- X{
- X Bufpos save;
- X File *fp;
- X
- X if (!is_insert) {
- X curbuf->b_ntbf = 0;
- X set_ino(curbuf);
- X }
- X fp = open_file(file, iobuff, F_READ, !COMPLAIN, !QUIET);
- X if (fp == NIL) {
- X if (!is_insert && errno == ENOENT)
- X s_mess("(new file)");
- X else
- X s_mess(IOerr("open", file));
- X return;
- X }
- X DOTsave(&save);
- X dofread(fp);
- X SetDot(&save);
- X if (is_insert && io_chars > 0)
- X modify();
- X getDOT();
- X close_file(fp);
- X}
- X
- Xdofread(fp)
- Xregister File *fp;
- X{
- X char end[LBSIZE];
- X int xeof = 0;
- X Line *savel = curline;
- X int savec = curchar;
- X disk_line f_getputl() ;
- X
- X strcpy(end, linebuf + curchar);
- X xeof = f_gets(fp, linebuf + curchar, LBSIZE - curchar);
- X SavLine(curline, linebuf);
- X if (!xeof) do {
- X curline = listput(curbuf, curline);
- X xeof = f_getputl(curline, fp);
- X } while (!xeof);
- X getDOT();
- X linecopy(linebuf, (curchar = strlen(linebuf)), end);
- X SavLine(curline, linebuf);
- X IFixMarks(savel, savec, curline, curchar);
- X}
- X
- XSaveFile()
- X{
- X if (IsModified(curbuf)) {
- X if (curbuf->b_fname == 0)
- X WriteFile();
- X else {
- X filemunge(curbuf->b_fname);
- X chk_mtime(curbuf, curbuf->b_fname, "save");
- X file_write(curbuf->b_fname, 0);
- X unmodify();
- X }
- X } else
- X message("No changes need to be written.");
- X}
- X
- Xchar *HomeDir; /* home directory */
- Xint HomeLen = -1; /* length of home directory string */
- X
- X#ifndef CHDIR
- X
- Xchar *
- Xpr_name(fname)
- Xchar *fname;
- X{
- X if (fname == 0)
- X return 0;
- X
- X if (strncmp(fname, HomeDir, HomeLen) == 0) {
- X static char name_buf[100];
- X
- X sprintf(name_buf, "~%s", fname + HomeLen);
- X return name_buf;
- X }
- X
- X return fname;
- X}
- X
- X#else
- X
- X#define NDIRS 5
- X
- Xprivate char *DirStack[NDIRS] = {0};
- Xprivate int DirSP = 0; /* Directory stack pointer */
- X#define PWD (DirStack[DirSP])
- X
- Xchar *
- Xpwd()
- X{
- X return PWD;
- X}
- X
- Xchar *
- Xpr_name(fname)
- Xchar *fname;
- X{
- X int n;
- X
- X if (fname == 0)
- X return 0;
- X n = numcomp(fname, PWD);
- X
- X if ((PWD[n] == 0) && /* Matched to end of PWD */
- X (fname[n] == '/'))
- X return fname + n + 1;
- X
- X if (strcmp(HomeDir, "/") != 0 && strncmp(fname, HomeDir, HomeLen) == 0) {
- X static char name_buf[100];
- X
- X sprintf(name_buf, "~%s", fname + HomeLen);
- X return name_buf;
- X }
- X
- X return fname; /* return entire path name */
- X}
- X
- XChdir()
- X{
- X char dirbuf[FILESIZE];
- X
- X (void) ask_file((char *) 0, PWD, dirbuf);
- X if (chdir(dirbuf) == -1) {
- X s_mess("cd: cannot change into %s.", dirbuf);
- X return;
- X }
- X UpdModLine++;
- X setCWD(dirbuf);
- X}
- X
- X#ifndef JOB_CONTROL
- Xchar *
- Xgetwd()
- X{
- X Buffer *old = curbuf;
- X char *ret_val;
- X
- X SetBuf(do_select((Window *) 0, "pwd-output"));
- X curbuf->b_type = B_PROCESS;
- X (void) UnixToBuf("pwd-output", NO, 0, YES, "/bin/pwd", (char *) 0);
- X ToFirst();
- X ret_val = sprint(linebuf);
- X SetBuf(old);
- X return ret_val;
- X}
- X#endif
- X
- XsetCWD(d)
- Xchar *d;
- X{
- X if (PWD == 0)
- X PWD = malloc((unsigned) strlen(d) + 1);
- X else {
- X extern char *ralloc();
- X
- X PWD = ralloc(PWD, strlen(d) + 1);
- X }
- X strcpy(PWD, d);
- X}
- X
- XgetCWD()
- X{
- X char *cwd = getenv("CWD");
- X#ifdef JOB_CONTROL
- X extern char *getwd();
- X char pathname[FILESIZE];
- X#endif
- X
- X if (cwd == 0)
- X#ifdef JOB_CONTROL
- X cwd = getwd(pathname);
- X#else
- X cwd = getwd();
- X#endif
- X
- X setCWD(cwd);
- X}
- X
- XprDIRS()
- X{
- X register int i;
- X
- X s_mess(": %f ");
- X for (i = DirSP; i >= 0; i--)
- X add_mess("%s ", pr_name(DirStack[i]));
- X}
- X
- XprCWD()
- X{
- X s_mess(": %f => \"%s\"", PWD);
- X}
- X
- XPushd()
- X{
- X char *newdir,
- X dirbuf[FILESIZE];
- X
- X newdir = ask_file((char *) 0, NullStr, dirbuf);
- X UpdModLine++;
- X if (*newdir == 0) { /* Wants to swap top two entries */
- X char *old_top;
- X
- X if (DirSP == 0)
- X complain("pushd: no other directory.");
- X old_top = PWD;
- X DirStack[DirSP] = DirStack[DirSP - 1];
- X DirStack[DirSP - 1] = old_top;
- X (void) chdir(PWD);
- X } else {
- X if (chdir(dirbuf) == -1) {
- X s_mess("pushd: cannot change into %s.", dirbuf);
- X return;
- X }
- X
- X if (DirSP + 1 >= NDIRS)
- X complain("pushd: full stack; max of %d pushes.", NDIRS);
- X DirSP++;
- X setCWD(dirbuf);
- X }
- X prDIRS();
- X}
- X
- XPopd()
- X{
- X if (DirSP == 0)
- X complain("popd: directory stack is empty.");
- X UpdModLine++;
- X free(PWD);
- X PWD = 0;
- X DirSP--;
- X (void) chdir(PWD); /* If this doesn't work, we's in deep shit. */
- X prDIRS();
- X}
- X
- Xprivate char *
- Xdbackup(base, offset, c)
- Xregister char *base,
- X *offset,
- X c;
- X{
- X while (offset > base && *--offset != c)
- X ;
- X return offset;
- X}
- X
- Xdfollow(file, into)
- Xchar *file,
- X *into;
- X{
- X char *dp,
- X *sp;
- X
- X if (*file == '/') { /* Absolute pathname */
- X strcpy(into, "/");
- X file++;
- X } else
- X strcpy(into, PWD);
- X dp = into + strlen(into);
- X
- X sp = file;
- X do {
- X if (*file == 0)
- X break;
- X if (sp = index(file, '/'))
- X *sp = 0;
- X if (strcmp(file, ".") == 0)
- X ; /* So it will get to the end of the loop */
- X else if (strcmp(file, "..") == 0) {
- X *(dp = dbackup(into, dp, '/')) = 0;
- X if (dp == into)
- X strcpy(into, "/"), dp = into + 1;
- X } else {
- X if (into[strlen(into) - 1] != '/')
- X (void) strcat(into, "/");
- X (void) strcat(into, file);
- X dp += strlen(file); /* stay at the end */
- X }
- X file = sp + 1;
- X } while (sp != 0);
- X}
- X
- X#endif CHDIR
- X
- Xget_hdir(user, buf)
- Xregister char *user,
- X *buf;
- X{
- X char fbuf[LBSIZE],
- X pattern[100];
- X register int u_len;
- X File *fp;
- X
- X u_len = strlen(user);
- X fp = open_file("/etc/passwd", fbuf, F_READ, COMPLAIN, QUIET);
- X sprintf(pattern, "%s:[^:]*:[^:]*:[^:]*:[^:]*:\\([^:]*\\):", user);
- X while (f_gets(fp, genbuf, LBSIZE) != EOF)
- X if ((strncmp(genbuf, user, u_len) == 0) &&
- X (LookingAt(pattern, genbuf, 0))) {
- X putmatch(1, buf, FILESIZE);
- X close_file(fp);
- X return;
- X }
- X f_close(fp);
- X complain("[unknown user: %s]", user);
- X}
- X
- XPathParse(name, intobuf)
- Xchar *name,
- X *intobuf;
- X{
- X char localbuf[FILESIZE];
- X
- X intobuf[0] = localbuf[0] = '\0';
- X if (*name == '\0')
- X return;
- X if (*name == '~') {
- X if (name[1] == '/' || name[1] == '\0') {
- X strcpy(localbuf, HomeDir);
- X name++;
- X } else {
- X char *uendp = index(name, '/'),
- X unamebuf[30];
- X
- X if (uendp == 0)
- X uendp = name + strlen(name);
- X name = name + 1;
- X null_ncpy(unamebuf, name, uendp - name);
- X get_hdir(unamebuf, localbuf);
- X name = uendp;
- X }
- X } else if (*name == '\\')
- X name++;
- X (void) strcat(localbuf, name);
- X#ifdef CHDIR
- X dfollow(localbuf, intobuf);
- X#else
- X strcpy(intobuf, localbuf);
- X#endif
- X}
- X
- Xfilemunge(newname)
- Xchar *newname;
- X{
- X struct stat stbuf;
- X
- X if (newname == 0)
- X return;
- X if (stat(newname, &stbuf))
- X return;
- X if ((stbuf.st_ino != curbuf->b_ino) &&
- X ((stbuf.st_mode & S_IFMT) != S_IFCHR) &&
- X (strcmp(newname, curbuf->b_fname) != 0)) {
- X rbell();
- X confirm("\"%s\" already exists; overwrite it? ", newname);
- X }
- X}
- X
- XWrtReg()
- X{
- X DoWriteReg(0);
- X}
- X
- XAppReg()
- X{
- X DoWriteReg(1);
- X}
- X
- Xint CreatMode = DFLT_MODE;
- X
- XDoWriteReg(app)
- X{
- X char fnamebuf[FILESIZE],
- X *fname;
- X Mark *mp = CurMark();
- X File *fp;
- X
- X /* Won't get here if there isn't a Mark */
- X fname = ask_file((char *) 0, (char *) 0, fnamebuf);
- X
- X#ifdef BACKUPFILES
- X if (!app) {
- X filemunge(fname);
- X
- X if (BkupOnWrite)
- X file_backup(fname);
- X }
- X#else
- X if (!app)
- X filemunge(fname);
- X#endif
- X
- X fp = open_file(fname, iobuff, app ? F_APPEND : F_WRITE, COMPLAIN, !QUIET);
- X putreg(fp, mp->m_line, mp->m_char, curline, curchar, YES);
- X close_file(fp);
- X}
- X
- Xint OkayBadChars = 0;
- X
- XWriteFile()
- X{
- X char *fname,
- X fnamebuf[FILESIZE];
- X
- X fname = ask_file((char *) 0, curbuf->b_fname, fnamebuf);
- X /* Don't allow bad characters when creating new files. */
- X if (!OkayBadChars && strcmp(curbuf->b_fname, fnamebuf) != 0) {
- X static char *badchars = "!$^&*()~`{}\"'\\|<>? ";
- X register char *cp = fnamebuf;
- X register int c;
- X
- X while (c = *cp++)
- X if (c < ' ' || c == '\177' || index(badchars, c))
- X complain("'%p': bad character in filename.", c);
- X }
- X
- X chk_mtime(curbuf, fname, "write");
- X filemunge(fname);
- X curbuf->b_type = B_FILE; /* In case it wasn't before. */
- X setfname(curbuf, fname);
- X file_write(fname, 0);
- X unmodify();
- X}
- X
- XFile *
- Xopen_file(fname, buf, how, ifbad, loudness)
- Xregister char *fname;
- Xchar *buf;
- Xregister int how;
- X{
- X register File *fp;
- X
- X io_chars = 0;
- X io_lines = 0;
- X tellall = loudness;
- X
- X fp = f_open(fname, how, buf, LBSIZE);
- X if (fp == NIL) {
- X message(IOerr((how == F_READ) ? "open" : "create", fname));
- X if (ifbad == COMPLAIN)
- X complain((char *) 0);
- X } else {
- X int readonly = FALSE;
- X
- X if (access(fname, W_OK) == -1 && errno != ENOENT)
- X readonly = TRUE;
- X
- X if (loudness != QUIET)
- X f_mess("\"%s\"%s", pr_name(fname),
- X readonly ? " [Read only]" : NullStr);
- X }
- X return fp;
- X}
- X
- X/* Check to see if the file has been modified since it was
- X last written. If so, make sure they know what they're
- X doing.
- X
- X I hate to use another stat(), but to use confirm we gotta
- X do this before we open the file. */
- X
- Xchk_mtime(thisbuf, fname, how)
- XBuffer *thisbuf;
- Xchar *fname,
- X *how;
- X{
- X struct stat stbuf;
- X Buffer *b;
- X char *mesg = "Shall I go ahead and %s anyway? ";
- X
- X if ((thisbuf->b_mtime != 0) && /* if we care ... */
- X (b = file_exists(fname)) && /* we already have this file */
- X (b == thisbuf) && /* and it's the current buffer */
- X (stat(fname, &stbuf) != -1) && /* and we can stat it */
- X (stbuf.st_mtime != b->b_mtime)) { /* and there's trouble. */
- X rbell();
- X redisplay(); /* Ring that bell! */
- X TOstart("Warning", TRUE);
- X Typeout("\"%s\" now saved on disk is not what you last", pr_name(fname));
- X Typeout("visited or saved. Probably someone else is editing");
- X Typeout("your file at the same time.");
- X if (how) {
- X Typeout("");
- X Typeout("Type \"y\" if I should %s, anyway.", how);
- X f_mess(mesg, how);
- X }
- X TOstop();
- X if (how)
- X confirm(mesg, how);
- X }
- X}
- X
- Xfile_write(fname, app)
- Xchar *fname;
- X{
- X File *fp;
- X
- X#ifdef BACKUPFILES
- X if (!app && BkupOnWrite)
- X file_backup(fname);
- X#endif
- X
- X fp = open_file(fname, iobuff, app ? F_APPEND : F_WRITE, COMPLAIN, !QUIET);
- X
- X if (EndWNewline) { /* Make sure file ends with a newLine */
- X Bufpos save;
- X
- X DOTsave(&save);
- X ToLast();
- X if (length(curline)) /* Not a blank Line */
- X LineInsert(1);
- X SetDot(&save);
- X }
- X putreg(fp, curbuf->b_first, 0, curbuf->b_last, length(curbuf->b_last), NO);
- X set_ino(curbuf);
- X close_file(fp);
- X}
- X
- XReadFile()
- X{
- X char *fname,
- X fnamebuf[FILESIZE];
- X
- X fname = ask_file((char *) 0, curbuf->b_fname, fnamebuf);
- X chk_mtime(curbuf, fname, "read");
- X
- X if (IsModified(curbuf)) {
- X char *y_or_n;
- X int c;
- X
- X for (;;) {
- X rbell();
- X y_or_n = ask(NullStr, "Shall I make your changes to \"%s\" permanent? ", curbuf->b_name);
- X c = Upper(*y_or_n);
- X if (c == 'Y' || c == 'N')
- X break;
- X }
- X if (c == 'Y')
- X SaveFile();
- X }
- X
- X unmodify();
- X initlist(curbuf);
- X setfname(curbuf, fname);
- X read_file(fname, 0);
- X}
- X
- XInsFile()
- X{
- X char *fname,
- X fnamebuf[FILESIZE];
- X
- X fname = ask_file((char *) 0, curbuf->b_fname, fnamebuf);
- X read_file(fname, 1);
- X}
- X
- X#include "temp.h"
- X
- Xint DOLsave = 0; /* Do Lsave flag. If lines aren't being save
- X when you think they should have been, this
- X flag is probably not being set, or is being
- X cleared before lsave() was called. */
- X
- Xprivate int nleft, /* number of good characters left in current block */
- X tmpfd = -1;
- Xprivate disk_line DFree = 1;
- X /* pointer to end of tmp file */
- Xprivate char *tfname;
- X
- Xtmpinit()
- X{
- X char buf[FILESIZE];
- X
- X sprintf(buf, "%s/%s", TmpFilePath, d_tempfile);
- X tfname = copystr(buf);
- X tfname = mktemp(tfname);
- X (void) close(creat(tfname, 0600));
- X tmpfd = open(tfname, 2);
- X if (tmpfd == -1)
- X complain("Warning: cannot create tmp file!");
- X}
- X
- Xtmpclose()
- X{
- X (void) close(tmpfd);
- X tmpfd = -1;
- X (void) unlink(tfname);
- X}
- X
- X/* Get a line at `tl' in the tmp file into `buf' which should be LBSIZE
- X long. */
- X
- Xint Jr_Len; /* Length of Just Read Line. */
- Xprivate char *getblock();
- X
- Xgetline(addr, buf)
- Xdisk_line addr;
- Xregister char *buf;
- X{
- X register char *bp,
- X *lp;
- X
- X lp = buf;
- X bp = getblock(addr >> 1, READ);
- X while (*lp++ = *bp++)
- X ;
- X Jr_Len = (lp - buf) - 1;
- X}
- X
- X/* Put `buf' and return the disk address */
- X
- Xdisk_line
- Xputline(buf)
- Xchar *buf;
- X{
- X register char *bp,
- X *lp;
- X register int nl;
- X disk_line free_ptr;
- X
- X lp = buf;
- X free_ptr = DFree;
- X bp = getblock(free_ptr, WRITE);
- X nl = nleft;
- X free_ptr = blk_round(free_ptr);
- X while (*bp = *lp++) {
- X if (*bp++ == '\n') {
- X *--bp = 0;
- X break;
- X }
- X if (--nl == 0) {
- X free_ptr = forward_block(free_ptr);
- X DFree = free_ptr;
- X bp = getblock(free_ptr, WRITE);
- X lp = buf; /* start over ... */
- X nl = nleft;
- X }
- X }
- X free_ptr = DFree;
- X DFree += (((lp - buf) + CH_SIZE - 1) / CH_SIZE);
- X /* (lp - buf) includes the null */
- X return (free_ptr << 1);
- X}
- X
- X/* The theory is that critical section of code inside this procedure
- X will never cause a problem to occur. Basically, we need to ensure
- X that two blocks are in memory at the same time, but I think that
- X this can never screw up. */
- X
- X#define lockblock(addr)
- X#define unlockblock(addr)
- X
- Xdisk_line
- Xf_getputl(line, fp)
- XLine *line;
- Xregister File *fp;
- X{
- X register char *bp;
- X register int c,
- X nl,
- X max = LBSIZE;
- X disk_line free_ptr;
- X char *base;
- X
- X free_ptr = DFree;
- X base = bp = getblock(free_ptr, WRITE);
- X nl = nleft;
- X free_ptr = blk_round(free_ptr);
- X while (--max > 0) {
- X c = getc(fp);
- X if (c == EOF || c == '\n')
- X break;
- X if (--nl == 0) {
- X char *newbp;
- X int nbytes;
- X
- X lockblock(free_ptr);
- X DFree = free_ptr = forward_block(free_ptr);
- X nbytes = bp - base;
- X newbp = getblock(free_ptr, WRITE);
- X nl = nleft;
- X byte_copy(base, newbp, nbytes);
- X bp = newbp + nbytes;
- X base = newbp;
- X unlockblock(free_ptr);
- X }
- X *bp++ = c;
- X }
- X *bp++ = '\0';
- X free_ptr = DFree;
- X DFree += (((bp - base) + CH_SIZE - 1) / CH_SIZE);
- X line->l_dline = (free_ptr << 1);
- X if (max == 0) {
- X add_mess(" [Line too long]");
- X rbell();
- X return EOF;
- X }
- X if (c == EOF) {
- X if (--bp != base)
- X add_mess(" [Incomplete last line]");
- X return EOF;
- X }
- X io_lines++;
- X return NIL;
- X}
- X
- Xtypedef struct block {
- X short b_dirty,
- X b_bno;
- X char b_buf[BUFSIZ];
- X struct block
- X *b_LRUnext,
- X *b_LRUprev,
- X *b_HASHnext;
- X} Block;
- X
- X#define HASHSIZE 7 /* Primes work best (so I'm told) */
- X#define B_HASH(bno) (bno % HASHSIZE)
- X
- Xprivate Block b_cache[NBUF],
- X *bht[HASHSIZE] = {0}, /* Block hash table */
- X *f_block = 0,
- X *l_block = 0;
- Xprivate int max_bno = -1,
- X NBlocks;
- X
- Xprivate int (*blkio)();
- X
- Xprivate
- Xreal_blkio(b, iofcn)
- Xregister Block *b;
- Xregister int (*iofcn)();
- X{
- X (void) lseek(tmpfd, (long) ((unsigned) b->b_bno) * BUFSIZ, 0);
- X if ((*iofcn)(tmpfd, b->b_buf, BUFSIZ) != BUFSIZ)
- X error("Tmp file %s error.", (iofcn == read) ? "read" : "write");
- X}
- X
- Xprivate
- Xfake_blkio(b, iofcn)
- Xregister Block *b;
- Xregister int (*iofcn)();
- X{
- X tmpinit();
- X blkio = real_blkio;
- X real_blkio(b, iofcn);
- X}
- X
- Xd_cache_init()
- X{
- X register Block *bp, /* Block pointer */
- X **hp; /* Hash pointer */
- X register short bno;
- X
- X for (bp = b_cache, bno = NBUF; --bno >= 0; bp++) {
- X NBlocks++;
- X bp->b_dirty = 0;
- X bp->b_bno = bno;
- X if (l_block == 0)
- X l_block = bp;
- X bp->b_LRUprev = 0;
- X bp->b_LRUnext = f_block;
- X if (f_block != 0)
- X f_block->b_LRUprev = bp;
- X f_block = bp;
- X
- X bp->b_HASHnext = *(hp = &bht[B_HASH(bno)]);
- X *hp = bp;
- X }
- X blkio = fake_blkio;
- X}
- X
- XSyncTmp()
- X{
- X#ifdef MSDOS
- X register int bno = 0;
- X BLock *lookup();
- X
- X for (bno = 0; bno <= max_bno; )
- X (*blkio)(lookup(bno++), write);
- X#else
- X register Block *b;
- X
- X for (b = f_block; b != 0; b = b->b_LRUnext)
- X if (b->b_dirty) {
- X (*blkio)(b, write);
- X b->b_dirty = 0;
- X }
- X#endif
- X}
- X
- Xprivate Block *
- Xlookup(bno)
- Xregister short bno;
- X{
- X register Block *bp;
- X
- X for (bp = bht[B_HASH(bno)]; bp != 0; bp = bp->b_HASHnext)
- X if (bp->b_bno == bno)
- X break;
- X return bp;
- X}
- X
- Xprivate
- XLRUunlink(b)
- Xregister Block *b;
- X{
- X if (b->b_LRUprev == 0)
- X f_block = b->b_LRUnext;
- X else
- X b->b_LRUprev->b_LRUnext = b->b_LRUnext;
- X if (b->b_LRUnext == 0)
- X l_block = b->b_LRUprev;
- X else
- X b->b_LRUnext->b_LRUprev = b->b_LRUprev;
- X}
- X
- Xprivate Block *
- Xb_unlink(bp)
- Xregister Block *bp;
- X{
- X register Block *hp,
- X *prev = 0;
- X
- X LRUunlink(bp);
- X /* Now that we have the block, we remove it from its position
- X in the hash table, so we can THEN put it somewhere else with
- X it's new block assignment. */
- X
- X for (hp = bht[B_HASH(bp->b_bno)]; hp != 0; prev = hp, hp = hp->b_HASHnext)
- X if (hp == bp)
- X break;
- X if (hp == 0) {
- X printf("\rBlock %d missing!", bp->b_bno);
- X finish(0);
- X }
- X if (prev)
- X prev->b_HASHnext = hp->b_HASHnext;
- X else
- X bht[B_HASH(bp->b_bno)] = hp->b_HASHnext;
- X
- X if (bp->b_dirty) { /* Do, now, the delayed write */
- X (*blkio)(bp, write);
- X bp->b_dirty = 0;
- X }
- X
- X return bp;
- X}
- X
- X/* Get a block which contains at least part of the line with the address
- X atl. Returns a pointer to the block and sets the global variable
- X nleft (number of good characters left in the buffer). */
- X
- Xprivate char *
- Xgetblock(atl, iof)
- Xdisk_line atl;
- X{
- X register int bno,
- X off;
- X register Block *bp;
- X static Block *lastb = 0;
- X
- X bno = daddr_to_bno(atl);
- X off = daddr_to_off(atl);
- X if (bno >= MAX_BLOCKS)
- X error("Tmp file too large. Get help!");
- X nleft = BUFSIZ - off;
- X if (lastb != 0 && lastb->b_bno == bno) {
- X lastb->b_dirty |= iof;
- X return lastb->b_buf + off;
- X }
- X
- X /* The requested block already lives in memory, so we move
- X it to the end of the LRU list (making it Most Recently Used)
- X and then return a pointer to it. */
- X if (bp = lookup(bno)) {
- X if (bp != l_block) {
- X LRUunlink(bp);
- X if (l_block == 0)
- X f_block = l_block = bp;
- X else
- X l_block->b_LRUnext = bp;
- X bp->b_LRUprev = l_block;
- X l_block = bp;
- X bp->b_LRUnext = 0;
- X }
- X if (bp->b_bno > max_bno)
- X max_bno = bp->b_bno;
- X bp->b_dirty |= iof;
- X lastb = bp;
- X return bp->b_buf + off;
- X }
- X
- X /* The block we want doesn't reside in memory so we take the
- X least recently used clean block (if there is one) and use
- X it. */
- X bp = f_block;
- X if (bp->b_dirty) /* The best block is dirty ... */
- X SyncTmp();
- X
- X bp = b_unlink(bp);
- X if (l_block == 0)
- X l_block = f_block = bp;
- X else
- X l_block->b_LRUnext = bp; /* Place it at the end ... */
- X bp->b_LRUprev = l_block;
- X l_block = bp;
- X bp->b_LRUnext = 0; /* so it's Most Recently Used */
- X
- X bp->b_dirty = iof;
- X bp->b_bno = bno;
- X bp->b_HASHnext = bht[B_HASH(bno)];
- X bht[B_HASH(bno)] = bp;
- X
- X /* Get the current contents of the block UNLESS this is a new
- X block that's never been looked at before, i.e., it's past
- X the end of the tmp file. */
- X
- X if (bp->b_bno <= max_bno)
- X (*blkio)(bp, read);
- X else
- X max_bno = bno;
- X
- X lastb = bp;
- X return bp->b_buf + off;
- X}
- X
- Xchar *
- Xlbptr(line)
- XLine *line;
- X{
- X return getblock(line->l_dline >> 1, READ);
- X}
- X
- X/* save the current contents of linebuf, if it has changed */
- X
- Xlsave()
- X{
- X if (curbuf == 0 || !DOLsave) /* Nothing modified recently */
- X return;
- X
- X if (strcmp(lbptr(curline), linebuf) != 0)
- X SavLine(curline, linebuf); /* Put linebuf on the disk. */
- X DOLsave = 0;
- X}
- X
- X#ifdef BACKUPFILES
- Xfile_backup(fname)
- Xchar *fname;
- X{
- X char *s;
- X register int i;
- X int fd1,
- X fd2;
- X char tmp1[BUFSIZ],
- X tmp2[BUFSIZ];
- X
- X strcpy(tmp1, fname);
- X
- X if ((s = rindex(tmp1, '/')) == NULL)
- X sprintf(tmp2, "#%s", fname);
- X else {
- X *s++ = '\0';
- X sprintf(tmp2, "%s/#%s", tmp1, s);
- X }
- X
- X if ((fd1 = open(fname, 0)) < 0)
- X return;
- X
- X if ((fd2 = creat(tmp2, CreatMode)) < 0) {
- X (void) close(fd1);
- X return;
- X }
- X
- X while ((i = read(fd1, tmp1, sizeof(tmp1))) > 0)
- X write(fd2, tmp1, i);
- X
- X#ifdef BSD4_2
- X (void) fsync(fd2);
- X#endif
- X (void) close(fd2);
- X (void) close(fd1);
- X}
- X#endif
- @//E*O*F io.c//
- if test 20767 -ne "`wc -c <'io.c'`"; then
- echo shar: error transmitting "'io.c'" '(should have been 20767 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'iproc-pipes.c'" '(5738 characters)'
- if test -f 'iproc-pipes.c' ; then
- echo shar: will not over-write existing file "'iproc-pipes.c'"
- else
- sed 's/^X//' >iproc-pipes.c <<'@//E*O*F iproc-pipes.c//'
- X/************************************************************************
- X * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is *
- X * provided to you without charge, and with no warranty. You may give *
- X * away copies of JOVE, including sources, provided that this notice is *
- X * included in all the files. *
- X ************************************************************************/
- X
- X#ifdef BSD4_2
- X# include <sys/wait.h>
- X#else
- X# include <wait.h>
- X#endif
- X#include <signal.h>
- X#include <sgtty.h>
- X
- Xtypedef struct process Process;
- X
- X#define DEAD 1 /* Dead but haven't informed user yet */
- X#define STOPPED 2 /* Job stopped */
- X#define RUNNING 3 /* Just running */
- X#define NEW 4 /* This process is brand new */
- X
- X/* If process is dead, flags says how. */
- X#define EXITED 1
- X#define KILLED 2
- X
- X#define isdead(p) (p == 0 || proc_state(p) == DEAD || p->p_toproc == -1)
- X
- X#define proc_buf(p) (p->p_buffer->b_name)
- X#define proc_cmd(p) (p->p_name)
- X#define proc_state(p) (p->p_state)
- X
- Xprivate Process *procs = 0;
- X
- Xint ProcInput,
- X ProcOutput,
- X NumProcs = 0;
- X
- Xstatic char *
- Xpstate(p)
- XProcess *p;
- X{
- X switch (proc_state(p)) {
- X case NEW:
- X return "Pre-birth";
- X
- X case STOPPED:
- X return "Stopped";
- X
- X case RUNNING:
- X return "Running";
- X
- X case DEAD:
- X if (p->p_howdied == EXITED) {
- X if (p->p_reason == 0)
- X return "Done";
- X return sprint("[Exit %d]", p->p_reason);
- X }
- X return sprint("[Killed %d]", p->p_reason);
- X
- X default:
- X return "Unknown state.";
- X }
- X}
- X
- Xstatic Process *
- Xproc_pid(pid)
- X{
- X register Process *p;
- X
- X for (p = procs; p != 0; p = p->p_next)
- X if (p->p_portpid == pid)
- X break;
- X
- X return p;
- X}
- X
- Xprocs_read()
- X{
- X struct header {
- X int pid;
- X int nbytes;
- X } header;
- X int n;
- X long nbytes;
- X static int here = 0;
- X
- X if (here)
- X return;
- X sighold(SIGCHLD); /* Block any other children. */
- X here++;
- X for (;;) {
- X (void) ioctl(ProcInput, FIONREAD, (struct sgttyb *) &nbytes);
- X if (nbytes < sizeof header)
- X break;
- X n = read(ProcInput, (char *) &header, sizeof header);
- X if (n != sizeof header)
- X finish(1);
- X read_proc(header.pid, header.nbytes);
- X }
- X redisplay();
- X here = 0;
- X sigrelse(SIGCHLD);
- X}
- X
- Xread_proc(pid, nbytes)
- Xint pid;
- Xregister int nbytes;
- X{
- X register Process *p;
- X int n;
- X char ibuf[512];
- X
- X if ((p = proc_pid(pid)) == 0) {
- X printf("\riproc: unknown pid (%d)", pid);
- X return;
- X }
- X if (proc_state(p) == NEW) {
- X int rpid;
- X /* Pid of real child, not of portsrv. */
- X
- X doread(ProcInput, (char *) &rpid, nbytes);
- X nbytes -= sizeof rpid;
- X p->p_pid = rpid;
- X p->p_state = RUNNING;
- X }
- X
- X if (nbytes == EOF) { /* Okay to clean up this process */
- X p->p_eof = 1;
- X NumProcs--; /* As far as getch() in main is concerned */
- X return;
- X }
- X
- X while (nbytes > 0) {
- X n = min((sizeof ibuf) - 1, nbytes);
- X doread(ProcInput, ibuf, n);
- X ibuf[n] = 0; /* Null terminate for convenience */
- X nbytes -= n;
- X proc_rec(p, ibuf);
- X }
- X}
- X
- XProcKill()
- X{
- X proc_kill(curbuf->b_process, SIGKILL);
- X}
- X
- XProcInt()
- X{
- X proc_kill(curbuf->b_process, SIGINT);
- X}
- X
- XProcQuit()
- X{
- X proc_kill(curbuf->b_process, SIGQUIT);
- X}
- X
- Xstatic
- Xproc_close(p)
- XProcess *p;
- X{
- X (void) close(p->p_toproc);
- X p->p_toproc = -1; /* Writes will fail. */
- X}
- X
- Xdo_rtp(mp)
- Xregister Mark *mp;
- X{
- X register Process *p = curbuf->b_process;
- X Line *line1 = curline,
- X *line2 = mp->m_line;
- X int char1 = curchar,
- X char2 = mp->m_char;
- X char *gp;
- X
- X if (isdead(p) || p->p_buffer != curbuf)
- X return;
- X
- X (void) fixorder(&line1, &char1, &line2, &char2);
- X while (line1 != line2->l_next) {
- X gp = ltobuf(line1, genbuf) + char1;
- X if (line1 == line2)
- X gp[char2] = '\0';
- X else
- X strcat(gp, "\n");
- X (void) write(p->p_toproc, gp, strlen(gp));
- X line1 = line1->l_next;
- X char1 = 0;
- X }
- X}
- X
- X/* VARARGS3 */
- X
- Xprivate
- Xproc_strt(bufname, clobber, va_alist)
- Xchar *bufname;
- Xva_dcl
- X{
- X Window *owind = curwind;
- X int toproc[2],
- X pid;
- X Process *newp;
- X Buffer *newbuf;
- X char *argv[32],
- X *cp,
- X foo[10],
- X cmdbuf[128];
- X int i;
- X va_list ap;
- X
- X isprocbuf(bufname); /* make sure BUFNAME is either nonexistant
- X or is of type B_PROCESS */
- X dopipe(toproc);
- X
- X switch (pid = fork()) {
- X case -1:
- X pclose(toproc);
- X complain("[Fork failed.]");
- X
- X case 0:
- X argv[0] = "portsrv";
- X argv[1] = foo;
- X sprintf(foo, "%d", ProcInput);
- X va_start(ap);
- X make_argv(&argv[2], ap);
- X va_end(ap);
- X (void) dup2(toproc[0], 0);
- X (void) dup2(ProcOutput, 1);
- X (void) dup2(ProcOutput, 2);
- X pclose(toproc);
- X execv(Portsrv, args);
- X printf("Execl failed.\n");
- X _exit(1);
- X }
- X
- X sighold(SIGCHLD);
- X newp = (Process *) malloc(sizeof *newp);
- X newp->p_next = procs;
- X newp->p_state = NEW;
- X newp->p_cmd = 0;
- X
- X cmdbuf[0] = '\0';
- X va_start(ap);
- X while (cp = va_arg(ap, char *))
- X sprintf(&cmdbuf[strlen(cmdbuf)], "%s ", cp);
- X va_end(ap);
- X newp->p_name = copystr(cmdbuf);
- X procs = newp;
- X newp->p_portpid = pid;
- X newp->p_pid = -1;
- X
- X newbuf = do_select((Window *) 0, bufname);
- X newbuf->b_type = B_PROCESS;
- X newp->p_buffer = newbuf;
- X newbuf->b_process = newp; /* sorta circular, eh? */
- X pop_wind(bufname, clobber, B_PROCESS);
- X ToLast();
- X if (!bolp())
- X LineInsert(1);
- X /* Pop_wind() after everything is set up; important!
- X Bindings won't work right unless newbuf->b_process is already
- X set up BEFORE NEWBUF is first SetBuf()'d. */
- X newp->p_mark = MakeMark(curline, curchar, FLOATER);
- X
- X newp->p_toproc = toproc[1];
- X newp->p_reason = 0;
- X newp->p_eof = 0;
- X NumProcs++;
- X (void) close(toproc[0]);
- X sigrelse(SIGCHLD);
- X SetWind(owind);
- X}
- X
- Xpinit()
- X{
- X int p[2];
- X
- X (void) signal(SIGCHLD, proc_child);
- X (void) pipe(p);
- X ProcInput = p[0];
- X ProcOutput = p[1];
- X (void) signal(INPUT_SIG, procs_read);
- X sighold(INPUT_SIG); /* Released during terminal read */
- X}
- X
- Xdoread(fd, buf, n)
- Xchar *buf;
- X{
- X int nread;
- X
- X if ((nread = read(fd, buf, n)) != n)
- X complain("Cannot read %d (got %d) bytes.", n, nread);
- X}
- @//E*O*F iproc-pipes.c//
- if test 5738 -ne "`wc -c <'iproc-pipes.c'`"; then
- echo shar: error transmitting "'iproc-pipes.c'" '(should have been 5738 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'iproc-ptys.c'" '(7160 characters)'
- if test -f 'iproc-ptys.c' ; then
- echo shar: will not over-write existing file "'iproc-ptys.c'"
- else
- sed 's/^X//' >iproc-ptys.c <<'@//E*O*F iproc-ptys.c//'
- X/************************************************************************
- X * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is *
- X * provided to you without charge, and with no warranty. You may give *
- X * away copies of JOVE, including sources, provided that this notice is *
- X * included in all the files. *
- X ************************************************************************/
- X
- X#ifdef BSD4_2
- X# include <sys/wait.h>
- X#else
- X# include <wait.h>
- X#endif
- X#include <signal.h>
- X#include <sgtty.h>
- X
- X#define DEAD 1 /* Dead but haven't informed user yet */
- X#define STOPPED 2 /* Job stopped */
- X#define RUNNING 3 /* Just running */
- X#define NEW 4 /* This process is brand new */
- X
- X/* If process is dead, flags says how. */
- X#define EXITED 1
- X#define KILLED 2
- X
- X#define isdead(p) (p == 0 || proc_state(p) == DEAD || p->p_fd == -1)
- X
- X#define proc_buf(p) (p->p_buffer->b_name)
- X#define proc_cmd(p) (p->p_name)
- X#define proc_state(p) (p->p_state)
- X
- Xprivate Process *procs = 0;
- X
- Xint global_fd = 1,
- X NumProcs = 0;
- X
- X#ifdef BRLUNIX
- X extern struct sg_brl sg1;
- X#else
- X extern struct sgttyb sg1;
- X#endif
- X
- Xextern struct tchars tc1;
- X
- X#ifdef TIOCSLTC
- X extern struct ltchars ls1;
- X#endif
- X
- Xstatic char *
- Xpstate(p)
- XProcess *p;
- X{
- X switch (proc_state(p)) {
- X case STOPPED:
- X return "Stopped";
- X
- X case RUNNING:
- X return "Running";
- X
- X case DEAD:
- X if (p->p_howdied == EXITED) {
- X if (p->p_reason == 0)
- X return "Done";
- X return sprint("exit(%d)", p->p_reason);
- X }
- X return sprint("Killed(%d)", p->p_reason);
- X
- X default:
- X return "Unknown state.";
- X }
- X}
- X
- Xstatic Process *
- Xproc_pid(pid)
- X{
- X register Process *p;
- X
- X for (p = procs; p != 0; p = p->p_next)
- X if (p->p_pid == pid)
- X break;
- X
- X return p;
- X}
- X
- Xread_proc(fd)
- Xregister int fd;
- X{
- X register Process *p;
- X unsigned int n;
- X char ibuf[1024];
- X
- X for (p = procs; p != 0; p = p->p_next)
- X if (p->p_fd == fd)
- X break;
- X
- X if (p == 0) {
- X printf("\riproc: unknown fd %d", fd);
- X return;
- X }
- X
- X n = read(fd, ibuf, sizeof(ibuf) - 1);
- X if (n == 0) {
- X proc_close(p);
- X NumProcs--;
- X return;
- X }
- X ibuf[n] = '\0';
- X proc_rec(p, ibuf);
- X redisplay();
- X}
- X
- XProcKill()
- X{
- X register Buffer *b;
- X Process *buf_to_proc();
- X char *bname;
- X
- X bname = ask_buf(curbuf);
- X
- X if ((b = buf_exists(bname)) == 0)
- X complain("[No such buffer]");
- X if (b->b_process == 0)
- X complain("%s not tied to a process.", bname);
- X proc_kill(b->b_process, SIGKILL);
- X}
- X
- XProcCont()
- X{
- X Process *p;
- X
- X if ((p = curbuf->b_process) == 0)
- X complain("[No process]");
- X if (p->p_state != DEAD) {
- X proc_kill(p, SIGCONT);
- X p->p_state = RUNNING;
- X }
- X}
- X
- XProcEof()
- X{
- X send_p(tc1.t_eofc);
- X}
- X
- XProcInt()
- X{
- X send_p(tc1.t_intrc);
- X}
- X
- XProcQuit()
- X{
- X send_p(tc1.t_quitc);
- X}
- X
- XProcStop()
- X{
- X send_p(ls1.t_suspc);
- X}
- X
- XProcDStop()
- X{
- X send_p(ls1.t_dsuspc);
- X}
- X
- Xsend_p(c)
- Xchar c;
- X{
- X Process *p;
- X
- X if ((p = curbuf->b_process) == 0)
- X complain("[No process]");
- X ToLast();
- X (void) write(p->p_fd, &c, 1);
- X}
- X
- Xstatic
- Xproc_close(p)
- XProcess *p;
- X{
- X (void) close(p->p_fd);
- X global_fd &= ~(1 << p->p_fd);
- X p->p_eof++;
- X}
- X
- Xdo_rtp(mp)
- Xregister Mark *mp;
- X{
- X register Process *p = curbuf->b_process;
- X Line *line1 = curline,
- X *line2 = mp->m_line;
- X int char1 = curchar,
- X char2 = mp->m_char;
- X char *gp;
- X
- X if (isdead(p) || p->p_buffer != curbuf)
- X return;
- X
- X (void) fixorder(&line1, &char1, &line2, &char2);
- X while (line1 != line2->l_next) {
- X gp = ltobuf(line1, genbuf) + char1;
- X if (line1 == line2)
- X gp[char2] = '\0';
- X else
- X strcat(gp, "\n");
- X (void) write(p->p_fd, gp, strlen(gp));
- X line1 = line1->l_next;
- X char1 = 0;
- X }
- X}
- X
- X/* VARARGS3 */
- X
- Xprivate
- Xproc_strt(bufname, clobber, va_alist)
- Xchar *bufname;
- Xva_dcl
- X{
- X va_list ap;
- X char *argv[32],
- X *cp;
- X Window *owind = curwind;
- X int pid;
- X Process *newp;
- X Buffer *newbuf;
- X int i,
- X f,
- X ttyfd;
- X long ldisc,
- X lmode;
- X register char *s,
- X *t;
- X extern int errno;
- X static char ttybuf[11],
- X ptybuf[11];
- X char cmdbuf[128];
- X#ifdef BRLUNIX
- X struct sg_brl sg;
- X#else
- X struct sgttyb sg;
- X#endif
- X
- X#ifdef TIOCGWINSZ
- X struct winsize win;
- X#else
- X# ifdef BTL_BLIT
- X# include <sys/jioctl.h>
- X struct jwinsize jwin;
- X# endif
- X#endif
- X
- X isprocbuf(bufname); /* make sure BUFNAME is either nonexistant
- X or is of type B_PROCESS */
- X for (s = "pqrs"; *s; s++) {
- X for (t = "0123456789abcdef"; *t; t++) {
- X sprintf(ptybuf, "/dev/pty%c%c", *s, *t);
- X if ((ttyfd = open(ptybuf, 2)) >= 0) {
- X strcpy(ttybuf, ptybuf);
- X ttybuf[5] = 't';
- X /* make sure both ends are available */
- X if ((i = open(ttybuf, 2)) < 0)
- X continue;
- X (void) close(i);
- X goto out;
- X }
- X }
- X }
- X
- Xout: if (s == 0 && t == 0)
- X complain("[Out of ptys!]");
- X
- X#ifdef TIOCGETD
- X (void) ioctl(0, TIOCGETD, (struct sgttyb *) &ldisc);
- X#endif
- X#ifdef TIOCLGET
- X (void) ioctl(0, TIOCLGET, (struct sgttyb *) &lmode);
- X#endif
- X#ifdef TIOCGWINSZ
- X (void) ioctl(0, TIOCGWINSZ, (struct sgttyb *) &win);
- X#else
- X# ifdef BTL_BLIT
- X (void) ioctl(0, JWINSIZE, (struct sgttyb *) &jwin);
- X# endif BTL_BLIT
- X#endif
- X
- X switch (pid = fork()) {
- X case -1:
- X (void) close(ttyfd);
- X complain("[Fork failed!]");
- X
- X case 0:
- X for (i = 0; i < 32; i++)
- X (void) close(i);
- X
- X#ifdef TIOCNOTTY
- X if ((i = open("/dev/tty", 2)) >= 0) {
- X (void) ioctl(i, TIOCNOTTY, (struct sgttyb *) 0);
- X (void) close(i);
- X }
- X#endif
- X i = open(ttybuf, 2);
- X for (f = 0; f <= 2; f++)
- X (void) dup2(i, f);
- X
- X#ifdef TIOCSETD
- X (void) ioctl(0, TIOCSETD, (struct sgttyb *) &ldisc);
- X#endif
- X#ifdef TIOCLSET
- X (void) ioctl(0, TIOCLSET, (struct sgttyb *) &lmode);
- X#endif
- X#ifdef TIOCSETC
- X (void) ioctl(0, TIOCSETC, (struct sgttyb *) &tc1);
- X#endif
- X#ifdef TIOCSLTC
- X (void) ioctl(0, TIOCSLTC, (struct sgttyb *) &ls1);
- X#endif
- X
- X#ifdef TIOCGWINSZ
- X# ifdef SIGWINCH
- X (void) signal(SIGWINCH, SIG_IGN);
- X# endif
- X win.ws_row = curwind->w_height;
- X (void) ioctl(0, TIOCSWINSZ, (struct sgttyb *) &win);
- X#else
- X# ifdef BTL_BLIT
- X jwin.bytesy = curwind->w_height;
- X (void) ioctl(0, JSWINSIZE, (struct sgttyb *) &jwin);
- X# endif
- X#endif
- X
- X sg = sg1;
- X sg.sg_flags &= ~(ECHO | CRMOD);
- X (void) stty(0, &sg);
- X
- X i = getpid();
- X (void) ioctl(0, TIOCSPGRP, (struct sgttyb *) &i);
- X (void) setpgrp(0, i);
- X va_start(ap);
- X make_argv(argv, ap);
- X va_end(ap);
- X execv(argv[0], &argv[1]);
- X (void) write(1, "execve failed!\n", 15);
- X _exit(errno + 1);
- X }
- X
- X sighold(SIGCHLD);
- X#ifdef SIGWINCH
- X sighold(SIGWINCH);
- X#endif
- X newp = (Process *) emalloc(sizeof *newp);
- X
- X newp->p_fd = ttyfd;
- X newp->p_pid = pid;
- X newp->p_eof = 0;
- X
- X newbuf = do_select((Window *) 0, bufname);
- X newbuf->b_type = B_PROCESS;
- X newp->p_buffer = newbuf;
- X newbuf->b_process = newp; /* sorta circular, eh? */
- X pop_wind(bufname, clobber, B_PROCESS);
- X /* Pop_wind() after everything is set up; important!
- X Bindings won't work right unless newbuf->b_process is already
- X set up BEFORE NEWBUF is first SetBuf()'d. */
- X ToLast();
- X if (!bolp())
- X LineInsert(1);
- X
- X cmdbuf[0] = '\0';
- X va_start(ap);
- X while (cp = va_arg(ap, char *))
- X sprintf(&cmdbuf[strlen(cmdbuf)], "%s ", cp++);
- X va_end(ap);
- X
- X newp->p_name = copystr(cmdbuf);
- X newp->p_state = RUNNING;
- X newp->p_reason = 0;
- X newp->p_mark = MakeMark(curline, curchar, FLOATER);
- X
- X newp->p_next = procs;
- X procs = newp;
- X NumProcs++;
- X global_fd |= 1 << newp->p_fd;
- X sigrelse(SIGCHLD);
- X SetWind(owind);
- X}
- X
- Xpinit()
- X{
- X (void) signal(SIGCHLD, proc_child);
- X}
- @//E*O*F iproc-ptys.c//
- if test 7160 -ne "`wc -c <'iproc-ptys.c'`"; then
- echo shar: error transmitting "'iproc-ptys.c'" '(should have been 7160 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'iproc.c'" '(6421 characters)'
- if test -f 'iproc.c' ; then
- echo shar: will not over-write existing file "'iproc.c'"
- else
- sed 's/^X//' >iproc.c <<'@//E*O*F iproc.c//'
- X/************************************************************************
- X * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is *
- X * provided to you without charge, and with no warranty. You may give *
- X * away copies of JOVE, including sources, provided that this notice is *
- X * included in all the files. *
- X ************************************************************************/
- X
- X#include "jove.h"
- X#include <varargs.h>
- X
- X#ifdef IPROCS
- X
- Xint proc_child();
- X
- X#ifdef PIPEPROCS
- X# include "iproc-pipes.c"
- X#else
- X# include "iproc-ptys.c"
- X#endif
- X
- Xchar proc_prompt[80] = "% ";
- X
- XKillProcs()
- X{
- X register Process *p;
- X register int killem = -1; /* -1 means undetermined */
- X register char *yorn;
- X
- X for (p = procs; p != 0; p = p->p_next)
- X if (!isdead(p)) {
- X if (killem == -1) {
- X yorn = ask("y", "Should I kill your i-processes? ");
- X killem = (Upper(*yorn) == 'Y');
- X }
- X if (killem)
- X proc_kill(p, SIGKILL);
- X }
- X}
- X
- Xpbuftiedp(b)
- Xregister Buffer *b;
- X{
- X register Process *p = b->b_process;
- X
- X if (!isdead(p))
- X complain("Process %s, attached to %b, is %s.",
- X proc_cmd(p), b, pstate(p));
- X}
- X
- X/* Process receive: receives the characters in buf, and appends them to
- X the buffer associated with p. */
- X
- Xstatic
- Xproc_rec(p, buf)
- Xregister Process *p;
- Xchar *buf;
- X{
- X Buffer *saveb = curbuf;
- X register Window *w;
- X register Mark *savepoint;
- X int sameplace = 0,
- X do_disp = 0;
- X
- X if (curwind->w_bufp == p->p_buffer)
- X w = curwind;
- X else
- X w = windbp(p->p_buffer); /* Is this window visible? */
- X if (w != 0)
- X do_disp = (in_window(w, p->p_mark->m_line) != -1);
- X SetBuf(p->p_buffer);
- X savepoint = MakeMark(curline, curchar, FLOATER);
- X ToMark(p->p_mark); /* Where output last stopped. */
- X if (savepoint->m_line == curline && savepoint->m_char == curchar)
- X sameplace++;
- X
- X ins_str(buf, YES);
- X if (do_disp) {
- X w->w_line = curline;
- X w->w_char = curchar;
- X redisplay();
- X }
- X MarkSet(p->p_mark, curline, curchar);
- X if (!sameplace)
- X ToMark(savepoint); /* Back to where we were. */
- X DelMark(savepoint);
- X SetBuf(saveb);
- X}
- X
- Xproc_kill(p, sig)
- Xregister Process *p;
- X{
- X if (isdead(p))
- X return;
- X if (killpg(p->p_pid, sig) == -1)
- X s_mess("Cannot kill %s!", proc_buf(p));
- X}
- X
- X/* Deal with a process' death. proc_rec turns on the FREEUP bit when it
- X it gets the "EOF" from portsrv. FREEUP'd processes get unlinked from
- X the list, and the proc stucture and proc_buf(p) get free'd up, here. */
- X
- Xprivate
- XDealWDeath()
- X{
- X register Process *p,
- X *next,
- X *prev = 0;
- X
- X for (p = procs; p != 0; p = next) {
- X next = p->p_next;
- X if (!p->p_eof) {
- X prev = p;
- X continue;
- X }
- X proc_close(p);
- X PopPBs(); /* not a process anymore */
- X p->p_buffer->b_process = 0; /* we're killing ourself */
- X free((char *) p->p_name);
- X free((char *) p);
- X if (prev)
- X prev->p_next = next;
- X else
- X procs = next;
- X }
- X}
- X
- XProcList()
- X{
- X register Process *p;
- X char *fmt = "%-15s %-15s %-8s %s",
- X pidstr[10];
- X
- X if (procs == 0) {
- X message("[No subprocesses]");
- X return;
- X }
- X TOstart("Process list", TRUE);
- X
- X Typeout(fmt, "Buffer", "Status", "Pid ", "Command");
- X Typeout(fmt, "------", "------", "--- ", "-------");
- X for (p = procs; p != 0; p = p->p_next) {
- X sprintf(pidstr, "%d", p->p_pid);
- X Typeout(fmt, proc_buf(p), pstate(p), pidstr, p->p_name);
- X }
- X DealWDeath();
- X TOstop();
- X}
- X
- XProcNewline()
- X{
- X SendData(YES);
- X}
- X
- XProcSendData()
- X{
- X SendData(NO);
- X}
- X
- Xprivate
- XSendData(newlinep)
- X{
- X register Process *p = curbuf->b_process;
- X
- X if (isdead(p))
- X return;
- X if (lastp(curline)) {
- X Eol();
- X if (newlinep)
- X LineInsert(1);
- X do_rtp(p->p_mark);
- X MarkSet(p->p_mark, curline, curchar);
- X } else {
- X Bol();
- X while (LookingAt(proc_prompt, linebuf, curchar))
- X SetDot(dosearch(proc_prompt, 1, 1));
- X strcpy(genbuf, linebuf + curchar);
- X ToLast();
- X ins_str(genbuf, NO);
- X }
- X}
- X
- XShellProc()
- X{
- X char *shbuf = "*shell*";
- X register Buffer *b;
- X
- X b = buf_exists(shbuf);
- X if (b == 0 || isdead(b->b_process))
- X proc_strt(shbuf, NO, Shell, "-i", (char *) 0);
- X pop_wind(shbuf, NO, -1);
- X}
- X
- XIprocess()
- X{
- X extern char ShcomBuf[100],
- X *MakeName();
- X register char *command;
- X
- X command = ask(ShcomBuf, ProcFmt);
- X null_ncpy(ShcomBuf, command, (sizeof ShcomBuf) - 1);
- X proc_strt(MakeName(command), YES, Shell, ShFlags, command, (char *) 0);
- X}
- X
- Xproc_child()
- X{
- X union wait w;
- X register int pid;
- X
- X for (;;) {
- X#ifndef VMUNIX
- X pid = wait2(&w.w_status, (WNOHANG | WUNTRACED));
- X#else
- X pid = wait3(&w, (WNOHANG | WUNTRACED), (struct rusage *) 0);
- X#endif
- X if (pid <= 0)
- X break;
- X kill_off(pid, w);
- X }
- X}
- X
- Xkill_off(pid, w)
- Xregister int pid;
- Xunion wait w;
- X{
- X char str[128];
- X register Process *child;
- X
- X if ((child = proc_pid(pid)) == 0)
- X return;
- X
- X if (WIFSTOPPED(w))
- X child->p_state = STOPPED;
- X else {
- X child->p_state = DEAD;
- X if (WIFEXITED(w))
- X child->p_howdied = EXITED;
- X else if (WIFSIGNALED(w)) {
- X child->p_reason = w.w_termsig;
- X child->p_howdied = KILLED;
- X }
- X proc_close(child);
- X }
- X sprintf(str, "[Process %s: %s]\n",
- X proc_cmd(child),
- X pstate(child));
- X proc_rec(child, str);
- X}
- X
- X/* Push/pod process bindings. I openly acknowledge that this is a
- X kludge, but I can't be bothered making it right. */
- X
- Xstruct proc_bind {
- X int pb_key;
- X data_obj **pb_map;
- X data_obj *pb_push;
- X data_obj *pb_cmd;
- X struct proc_bind *pb_next;
- X};
- X
- Xstruct proc_bind *PBinds = 0;
- X
- XPopPBs()
- X{
- X register struct proc_bind *p;
- X
- X for (p = PBinds; p != 0; p = p->pb_next)
- X p->pb_map[p->pb_key] = p->pb_push;
- X}
- X
- XPushPBs()
- X{
- X register struct proc_bind *p;
- X
- X for (p = PBinds; p != 0; p = p->pb_next) {
- X p->pb_push = p->pb_map[p->pb_key];
- X p->pb_map[p->pb_key] = p->pb_cmd;
- X }
- X}
- X/* VARARGS0 */
- X
- XProcBind()
- X{
- X register data_obj *d;
- X
- X if ((d = findcom(ProcFmt)) == 0)
- X return;
- X s_mess(": %f %s ", d->Name);
- X ProcB2(mainmap, EOF, d);
- X}
- X
- XProcB2(map, lastkey, cmd)
- Xdata_obj **map,
- X *cmd;
- X{
- X register struct proc_bind *p;
- X register data_obj **nextmap;
- X int c;
- X
- X c = addgetc();
- X if (c == EOF) {
- X if (lastkey == EOF)
- X complain("[Empty key sequence]");
- X complain("[Unexpected end-of-line]");
- X } else {
- X if (nextmap = IsPrefix(map[c]))
- X ProcB2(nextmap, c, cmd);
- X else {
- X if (curbuf->b_process)
- X PopPBs();
- X
- X for (p = PBinds; p != 0; p = p->pb_next)
- X if (p->pb_key == c && p->pb_map == map)
- X break;
- X if (p == 0) {
- X p = (struct proc_bind *) emalloc(sizeof *p);
- X p->pb_next = PBinds;
- X PBinds = p;
- X }
- X p->pb_map = map;
- X p->pb_key = c;
- X p->pb_cmd = cmd;
- X
- X if (curbuf->b_process)
- X PushPBs();
- X }
- X }
- X}
- X
- X#endif IPROCS
- @//E*O*F iproc.c//
- if test 6421 -ne "`wc -c <'iproc.c'`"; then
- echo shar: error transmitting "'iproc.c'" '(should have been 6421 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'keymaps.txt'" '(10930 characters)'
- if test -f 'keymaps.txt' ; then
- echo shar: will not over-write existing file "'keymaps.txt'"
- else
- sed 's/^X//' >keymaps.txt <<'@//E*O*F keymaps.txt//'
- X/************************************************************************
- X * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is *
- X * provided to you without charge, and with no warranty. You may give *
- X * away copies of JOVE, including sources, provided that this notice is *
- X * included in all the files. *
- X ************************************************************************/
- X
- X/* Warning: You probably shouldn't put ifdefs anywhere *inside* the keymaps
- X definitions. It'll screw up the stuff in comments (at least), and maybe
- X a few other things. Yes, it *WILL* screw up the comments ... but it's
- X not clear that you care ... */
- X
- X#include "jove.h"
- X
- Xkeymap mainmap = {
- X "set-mark", /* ^@ */
- X "beginning-of-line", /* ^A */
- X "backward-character", /* ^B */
- X "unbound", /* ^C */
- X "delete-next-character", /* ^D */
- X "end-of-line", /* ^E */
- X "forward-character", /* ^F */
- X "unbound", /* ^G */
- X "delete-previous-character", /* ^H */
- X "handle-tab", /* ^I */
- X "newline-and-indent", /* ^J */
- X "kill-to-end-of-line", /* ^K */
- X "redraw-display", /* ^L */
- X "newline", /* ^M */
- X "next-line", /* ^N */
- X "newline-and-backup", /* ^O */
- X "previous-line", /* ^P */
- X "quoted-insert", /* ^Q */
- X "search-reverse", /* ^R */
- X "search-forward", /* ^S */
- X "transpose-characters", /* ^T */
- X "quadruple-numeric-argument", /* ^U */
- X "next-page", /* ^V */
- X "kill-region", /* ^W */
- X "prefix-2", /* ^X */
- X "yank", /* ^Y */
- X "scroll-up", /* ^Z */
- X "prefix-1", /* ^[ */
- X "search-forward", /* ^\ */
- X "unbound", /* ^] */
- X "quoted-insert", /* ^^ */
- X "unbound", /* ^_ */
- X "self-insert", /* */
- X "self-insert", /* ! */
- X "self-insert", /* " */
- X "self-insert", /* # */
- X "self-insert", /* $ */
- X "self-insert", /* % */
- X "self-insert", /* & */
- X "self-insert", /* ' */
- X "self-insert", /* ( */
- X "paren-flash", /* ) */
- X "self-insert", /* * */
- X "self-insert", /* + */
- X "self-insert", /* , */
- X "self-insert", /* - */
- X "self-insert", /* . */
- X "self-insert", /* / */
- X "self-insert", /* 0 */
- X "self-insert", /* 1 */
- X "self-insert", /* 2 */
- X "self-insert", /* 3 */
- X "self-insert", /* 4 */
- X "self-insert", /* 5 */
- X "self-insert", /* 6 */
- X "self-insert", /* 7 */
- X "self-insert", /* 8 */
- X "self-insert", /* 9 */
- X "self-insert", /* : */
- X "self-insert", /* ; */
- X "self-insert", /* < */
- X "self-insert", /* = */
- X "self-insert", /* > */
- X "self-insert", /* ? */
- X "self-insert", /* @ */
- X "self-insert", /* A */
- X "self-insert", /* B */
- X "self-insert", /* C */
- X "self-insert", /* D */
- X "self-insert", /* E */
- X "self-insert", /* F */
- X "self-insert", /* G */
- X "self-insert", /* H */
- X "self-insert", /* I */
- X "self-insert", /* J */
- X "self-insert", /* K */
- X "self-insert", /* L */
- X "self-insert", /* M */
- X "self-insert", /* N */
- X "self-insert", /* O */
- X "self-insert", /* P */
- X "self-insert", /* Q */
- X "self-insert", /* R */
- X "self-insert", /* S */
- X "self-insert", /* T */
- X "self-insert", /* U */
- X "self-insert", /* V */
- X "self-insert", /* W */
- X "self-insert", /* X */
- X "self-insert", /* Y */
- X "self-insert", /* Z */
- X "self-insert", /* [ */
- X "self-insert", /* \ */
- X "paren-flash", /* ] */
- X "self-insert", /* ^ */
- X "self-insert", /* _ */
- X "self-insert", /* ` */
- X "self-insert", /* a */
- X "self-insert", /* b */
- X "self-insert", /* c */
- X "self-insert", /* d */
- X "self-insert", /* e */
- X "self-insert", /* f */
- X "self-insert", /* g */
- X "self-insert", /* h */
- X "self-insert", /* i */
- X "self-insert", /* j */
- X "self-insert", /* k */
- X "self-insert", /* l */
- X "self-insert", /* m */
- X "self-insert", /* n */
- X "self-insert", /* o */
- X "self-insert", /* p */
- X "self-insert", /* q */
- X "self-insert", /* r */
- X "self-insert", /* s */
- X "self-insert", /* t */
- X "self-insert", /* u */
- X "self-insert", /* v */
- X "self-insert", /* w */
- X "self-insert", /* x */
- X "self-insert", /* y */
- X "self-insert", /* z */
- X "self-insert", /* { */
- X "self-insert", /* | */
- X "paren-flash", /* } */
- X "self-insert", /* ~ */
- X "delete-previous-character" /* ^? */
- X};
- X
- Xstruct data_obj *pref1map[0200] = {
- X "unbound", /* ^@ */
- X "unbound", /* ^A */
- X "backward-s-expression", /* ^B */
- X "unbound", /* ^C */
- X "down-list", /* ^D */
- X "unbound", /* ^E */
- X "forward-s-expression", /* ^F */
- X "unbound", /* ^G */
- X "unbound", /* ^H */
- X "unbound", /* ^I */
- X "unbound", /* ^J */
- X "kill-s-expression", /* ^K */
- X "clear-and-redraw", /* ^L */
- X "unbound", /* ^M */
- X "forward-list", /* ^N */
- X "unbound", /* ^O */
- X "backward-list", /* ^P */
- X "unbound", /* ^Q */
- X "unbound", /* ^R */
- X "unbound", /* ^S */
- X "unbound", /* ^T */
- X "backward-up-list", /* ^U */
- X "page-next-window", /* ^V */
- X "unbound", /* ^W */
- X "unbound", /* ^X */
- X "unbound", /* ^Y */
- X "unbound", /* ^Z */
- X "unbound", /* ^[ */
- X "unbound", /* ^\ */
- X "unbound", /* ^] */
- X "unbound", /* ^^ */
- X "unbound", /* ^_ */
- X "unbound", /* */
- X "unbound", /* ! */
- X "unbound", /* " */
- X "unbound", /* # */
- X "unbound", /* $ */
- X "unbound", /* % */
- X "unbound", /* & */
- X "unbound", /* ' */
- X "unbound", /* ( */
- X "unbound", /* ) */
- X "unbound", /* * */
- X "unbound", /* + */
- X "beginning-of-window", /* , */
- X "digit", /* - */
- X "end-of-window", /* . */
- X "unbound", /* / */
- X "digit", /* 0 */
- X "digit", /* 1 */
- X "digit", /* 2 */
- X "digit", /* 3 */
- X "digit", /* 4 */
- X "digit", /* 5 */
- X "digit", /* 6 */
- X "digit", /* 7 */
- X "digit", /* 8 */
- X "digit", /* 9 */
- X "unbound", /* : */
- X "unbound", /* ; */
- X "beginning-of-file", /* < */
- X "unbound", /* = */
- X "end-of-file", /* > */
- X "describe-command", /* ? */
- X "unbound", /* @ */
- X "backward-sentence", /* A */
- X "backward-word", /* B */
- X "case-word-capitalize", /* C */
- X "kill-next-word", /* D */
- X "forward-sentence", /* E */
- X "forward-word", /* F */
- X "goto-line", /* G */
- X "unbound", /* H */
- X "make-macro-interactive", /* I */
- X "fill-paragraph", /* J */
- X "kill-to-end-of-sentence", /* K */
- X "case-word-lower", /* L */
- X "first-non-blank", /* M */
- X "unbound", /* N */
- X "unbound", /* O */
- X "unbound", /* P */
- X "query-replace-string", /* Q */
- X "replace-string", /* R */
- X "unbound", /* S */
- X "unbound", /* T */
- X "case-word-upper", /* U */
- X "previous-page", /* V */
- X "copy-region", /* W */
- X "execute-named-command", /* X */
- X "yank-pop", /* Y */
- X "scroll-down", /* Z */
- X "backward-paragraph", /* [ */
- X "delete-white-space", /* \ */
- X "forward-paragraph", /* ] */
- X "unbound", /* ^ */
- X "unbound", /* _ */
- X "unbound", /* ` */
- X "backward-sentence", /* a */
- X "backward-word", /* b */
- X "case-word-capitalize", /* c */
- X "kill-next-word", /* d */
- X "forward-sentence", /* e */
- X "forward-word", /* f */
- X "goto-line", /* g */
- X "unbound", /* h */
- X "make-macro-interactive", /* i */
- X "fill-paragraph", /* j */
- X "kill-to-end-of-sentence", /* k */
- X "case-word-lower", /* l */
- X "first-non-blank", /* m */
- X "unbound", /* n */
- X "unbound", /* o */
- X "unbound", /* p */
- X "query-replace-string", /* q */
- X "replace-string", /* r */
- X "unbound", /* s */
- X "unbound", /* t */
- X "case-word-upper", /* u */
- X "previous-page", /* v */
- X "copy-region", /* w */
- X "execute-named-command", /* x */
- X "yank-pop", /* y */
- X "scroll-down", /* z */
- X "unbound", /* { */
- X "unbound", /* | */
- X "unbound", /* } */
- X "make-buffer-unmodified", /* ~ */
- X "kill-previous-word" /* ^? */
- X};
- X
- Xkeymap pref2map = {
- X "unbound", /* ^@ */
- X "unbound", /* ^A */
- X "list-buffers", /* ^B */
- X "exit-jove", /* ^C */
- X "unbound", /* ^D */
- X "compile-it", /* ^E */
- X "find-file", /* ^F */
- X "unbound", /* ^G */
- X "unbound", /* ^H */
- X "insert-file", /* ^I */
- X "unbound", /* ^J */
- X "unbound", /* ^K */
- X "unbound", /* ^L */
- X "write-modified-files", /* ^M */
- X "next-error", /* ^N */
- X "delete-blank-lines", /* ^O */
- X "previous-error", /* ^P */
- X "unbound", /* ^Q */
- X "visit-file", /* ^R */
- X "save-file", /* ^S */
- X "transpose-lines", /* ^T */
- X "unbound", /* ^U */
- X "visit-file", /* ^V */
- X "write-file", /* ^W */
- X "exchange-point-and-mark", /* ^X */
- X "unbound", /* ^Y */
- X "unbound", /* ^Z */
- X "unbound", /* ^[ */
- X "save-file", /* ^\ */
- X "unbound", /* ^] */
- X "unbound", /* ^^ */
- X "unbound", /* ^_ */
- X "unbound", /* */
- X "shell-command", /* ! */
- X "unbound", /* " */
- X "unbound", /* # */
- X "unbound", /* $ */
- X "unbound", /* % */
- X "unbound", /* & */
- X "unbound", /* ' */
- X "start-remember", /* ( */
- X "stop-remembering", /* ) */
- X "unbound", /* * */
- X "unbound", /* + */
- X "unbound", /* , */
- X "unbound", /* - */
- X "unbound", /* . */
- X "unbound", /* / */
- X "unbound", /* 0 */
- X "delete-other-windows", /* 1 */
- X "split-current-window", /* 2 */
- X "unbound", /* 3 */
- X "window-find", /* 4 */
- X "unbound", /* 5 */
- X "unbound", /* 6 */
- X "unbound", /* 7 */
- X "unbound", /* 8 */
- X "unbound", /* 9 */
- X "unbound", /* : */
- X "unbound", /* ; */
- X "unbound", /* < */
- X "unbound", /* = */
- X "unbound", /* > */
- X "describe-key", /* ? */
- X "unbound", /* @ */
- X "unbound", /* A */
- X "select-buffer", /* B */
- X "unbound", /* C */
- X "delete-current-window", /* D */
- X "execute-keyboard-macro", /* E */
- X "unbound", /* F */
- X "unbound", /* G */
- X "unbound", /* H */
- X "unbound", /* I */
- X "unbound", /* J */
- X "delete-buffer", /* K */
- X "unbound", /* L */
- X "unbound", /* M */
- X "next-window", /* N */
- X "previous-window", /* O */
- X "previous-window", /* P */
- X "unbound", /* Q */
- X "unbound", /* R */
- X "save-file", /* S */
- X "find-tag", /* T */
- X "unbound", /* U */
- X "unbound", /* V */
- X "unbound", /* W */
- X "unbound", /* X */
- X "unbound", /* Y */
- X "unbound", /* Z */
- X "unbound", /* [ */
- X "unbound", /* \ */
- X "unbound", /* ] */
- X "grow-window", /* ^ */
- X "unbound", /* _ */
- X "unbound", /* ` */
- X "unbound", /* a */
- X "select-buffer", /* b */
- X "unbound", /* c */
- X "delete-current-window", /* d */
- X "execute-keyboard-macro", /* e */
- X "unbound", /* f */
- X "unbound", /* g */
- X "unbound", /* h */
- X "unbound", /* i */
- X "unbound", /* j */
- X "delete-buffer", /* k */
- X "unbound", /* l */
- X "unbound", /* m */
- X "next-window", /* n */
- X "previous-window", /* o */
- X "previous-window", /* p */
- X "unbound", /* q */
- X "unbound", /* r */
- X "save-file", /* s */
- X "find-tag", /* t */
- X "unbound", /* u */
- X "unbound", /* v */
- X "unbound", /* w */
- X "unbound", /* x */
- X "unbound", /* y */
- X "unbound", /* z */
- X "unbound", /* { */
- X "unbound", /* | */
- X "unbound", /* } */
- X "unbound", /* ~ */
- X "kill-to-beginning-of-sentence" /* ^? */
- X};
- X
- Xkeymap miscmap = {0};
- @//E*O*F keymaps.txt//
- if test 10930 -ne "`wc -c <'keymaps.txt'`"; then
- echo shar: error transmitting "'keymaps.txt'" '(should have been 10930 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'rec.c'" '(2901 characters)'
- if test -f 'rec.c' ; then
- echo shar: will not over-write existing file "'rec.c'"
- else
- sed 's/^X//' >rec.c <<'@//E*O*F rec.c//'
- X/************************************************************************
- X * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is *
- X * provided to you without charge, and with no warranty. You may give *
- X * away copies of JOVE, including sources, provided that this notice is *
- X * included in all the files. *
- X ************************************************************************/
- X
- X#include "jove.h"
- X#include "io.h"
- X#include "rec.h"
- X#include <sys/file.h>
- X
- Xprivate int rec_fd = 0;
- Xprivate char *recfname;
- Xprivate File *rec_out;
- X
- X#ifndef L_SET
- X# define L_SET 0
- X#endif
- X
- Xprivate struct rec_head Header;
- X
- Xrecinit()
- X{
- X char buf[128];
- X
- X sprintf(buf, "%s/%s", TmpFilePath, p_tempfile);
- X recfname = copystr(buf);
- X recfname = mktemp(recfname);
- X rec_fd = creat(recfname, 0644);
- X if (rec_fd == -1) {
- X complain("Cannot create \"%s\"; recovery disabled.", recfname);
- X return;
- X }
- X /* Initialize the record IO. */
- X rec_out = fd_open(recfname, F_WRITE|F_LOCKED, rec_fd, iobuff, LBSIZE);
- X
- X /* Initialize the record header. */
- X Header.Uid = getuid();
- X Header.Pid = getpid();
- X Header.UpdTime = 0L;
- X Header.Nbuffers = 0;
- X (void) write(rec_fd, (char *) &Header, sizeof Header);
- X}
- X
- Xrecclose()
- X{
- X if (rec_fd == -1)
- X return;
- X (void) close(rec_fd);
- X (void) unlink(recfname);
- X}
- X
- Xstatic
- Xputaddr(addr, p)
- Xdisk_line addr;
- Xregister File *p;
- X{
- X register char *cp = (char *) &addr;
- X register int nchars = sizeof (disk_line);
- X
- X while (--nchars >= 0)
- X putc(*cp++ & 0377, p);
- X}
- X
- Xstatic
- Xputn(cp, nbytes)
- Xregister char *cp;
- Xregister int nbytes;
- X{
- X while (--nbytes >= 0)
- X putc(*cp++ & 0377, rec_out);
- X}
- X
- X/* Write out the line pointers for buffer B. */
- X
- Xstatic
- Xdmppntrs(b)
- Xregister Buffer *b;
- X{
- X register Line *lp;
- X
- X for (lp = b->b_first; lp != 0; lp = lp->l_next)
- X putaddr(lp->l_dline, rec_out);
- X}
- X
- X/* dump the buffer info and then the actual line pointers. */
- X
- Xstatic
- Xdmp_buf(b)
- Xregister Buffer *b;
- X{
- X static struct rec_entry record;
- X register Line *lp;
- X register int nlines = 0;
- X
- X for (lp = b->b_first; lp != 0; lp = lp->l_next, nlines++)
- X ;
- X strcpy(record.r_fname, b->b_fname ? b->b_fname : NullStr);
- X strcpy(record.r_bname, b->b_name);
- X record.r_nlines = nlines;
- X putn((char *) &record, sizeof record);
- X dmppntrs(b);
- X}
- X
- X/* Goes through all the buffers and syncs them to the disk. */
- X
- Xint SyncFreq = 50;
- X
- XSyncRec()
- X{
- X register Buffer *b;
- X
- X if (rec_fd == 0)
- X recinit(); /* Init recover file. */
- X if (rec_fd == -1)
- X return;
- X lseek(rec_fd, 0L, L_SET);
- X (void) time(&Header.UpdTime);
- X Header.Nbuffers = 0;
- X for (b = world; b != 0; b = b->b_next)
- X if (b->b_type == B_SCRATCH || !IsModified(b))
- X continue;
- X else
- X Header.Nbuffers++;
- X putn((char *) &Header, sizeof Header);
- X if (Header.Nbuffers != 0) {
- X SyncTmp();
- X for (b = world; b != 0; b = b->b_next)
- X if (b->b_type == B_SCRATCH || !IsModified(b))
- X continue;
- X else
- X dmp_buf(b);
- X }
- X flush(rec_out);
- X}
- @//E*O*F rec.c//
- if test 2901 -ne "`wc -c <'rec.c'`"; then
- echo shar: error transmitting "'rec.c'" '(should have been 2901 characters)'
- fi
- fi # end of overwriting check
- echo shar: "End of archive 4 (of 13)."
- cp /dev/null ark4isdone
- DONE=true
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13; do
- if test -f ark${I}isdone; then
- echo "You have run archive ${I}."
- else
- echo "You still need to run archive ${I}."
- DONE=false
- fi
- done
- case $DONE in
- true)
- echo "You have run all 13 archives."
- echo 'Now read the README and Makefile.'
- ;;
- esac
- ## End of shell archive.
- exit 0
-